/**
 * @file Coord.cpp
 * @author BadFatCat0919 (543015378@qq.com)
 * @brief 坐标类
 */

#include "Coord.h"
#include <cmath>

/**
 * @brief 判等
 * @param another 待判值
 * @return true 相等
 * @return false 不等
 */
bool Coord::operator==(const Coord &another) {
    return this->x == another.x && this->y == another.y;
}

/**
 * @brief 判不等
 * @param another 待判值
 * @return true 不等
 * @return false 相等
 */
bool Coord::operator!=(const Coord &another) {
    return !(*this == another);
}

/**
 * @brief 加法
 * @param another 另一运算元
 * @return Coord 相加结果
 */
Coord Coord::operator+(const Coord &another) {
    return Coord(this->x + another.x, this->y + another.y);
}

/**
 * @brief 减法
 * @param another 另一运算元
 * @return Coord 相减结果
 */
Coord Coord::operator-(const Coord &another) {
    return Coord(this->x - another.x, this->y - another.y);
}

/**
 * @brief 设置坐标值
 * @param x 横坐标
 * @param y 纵坐标
 */
void Coord::set(double x, double y) {
    this->x = x;
    this->y = y;
}

/**
 * @brief 根据格数设置坐标值
 * @param x 横坐标格数
 * @param y 纵坐标格数
 */
void Coord::set(int x, int y) {
    this->x = x * 0.5 + 0.25;
    this->y = y * 0.5 + 0.25;
}

/**
 * @brief 赋值
 * @param newValue 新值
 */
void Coord::set(const Coord &newValue) {
    this->x = newValue.x;
    this->y = newValue.y;
}

/**
 * @brief 获取目标的方位角
 * @param target 目标
 * @param whenEqual 当目标坐标与当前坐标相等时的默认值
 * @return double 目标的方位角
 */
double Coord::toward(Coord target, double whenEqual) {
    if(*this == target) {
        return whenEqual;
    }
    double result = std::atan((target.y - this->y) / (target.x - this->x));
    if(target.y >= this->y) {
        if(target.x >= this->x) {
            return result;
        } else {
            return result + PI;
        }
    } else {
        if(target.x < this->x) {
            return result - PI;
        } else {
            return result;
        }
    }
}

/**
 * @brief 到目标点的距离
 * @param target 目标点
 * @return double 距离
 */
double Coord::distance(Coord target) {
    return std::sqrt(std::pow((this->x - target.x), 2) + std::pow((this->y - target.y), 2));
}

/**
 * @brief 获取将坐标轴划分为格子后的横坐标
 * @param xScale 一格的宽度
 * @return int 将坐标轴划分为格子后的横坐标
 */
int Coord::getCellX(double xScale) {
    return std::floor(this->x / xScale);
}

/**
 * @brief 获取将坐标轴划分为格子后的纵坐标
 * @param yScale 一格的高度
 * @return int 将坐标轴划分为格子后的纵坐标
 */
int Coord::getCellY(double yScale) {
    return std::floor(this->y / yScale);
}
